package com.fiona.ioc.factory;


import java.lang.reflect.Method;
import java.util.Map;

import com.fiona.annotation.FionaAop;
import com.fiona.common.constant.FionaConstant;
import com.fiona.common.constant.FionaSpace;
import com.fiona.core.load.LoadHelper;
import com.fiona.core.model.FionaBeanModel;
import com.fiona.core.proxy.FionaCglibProxy;

/**
 * bean工厂
 * @author huacongnan
 *
 */
public class BeanFactory {

	private static FionaSpace constants = FionaSpace.getFionaSpace();
	
	/**
	 * 创建bean
	 * @param className lei
	 * @return beanObject
	 *
	 * @throws Exception 异常
	 */
	public static Object createBean(Class<?> className) throws Exception {
		try {

			Object hasStart = constants.getAttr(FionaConstant.HAS_START);
			if(hasStart != null){
				throw new Exception("只有Fiona才可以调用此方法，不可以手动显式调用");
			}
			Method[] methods = className.getDeclaredMethods();
			if(methods != null && methods.length > 0){
				for(Method method : methods){
					FionaAop fionaAop = method.getAnnotation(FionaAop.class);
//					Traction traction = method.getAnnotation(Traction.class);
//					RedisLock redisLock = method.getAnnotation(RedisLock.class);
					if(fionaAop != null){
						/* 如果bean里面用到了AOP，就从动态代理创建对象 */
						FionaCglibProxy fionaBeanProxy = new FionaCglibProxy();
						return fionaBeanProxy.getProxy(className);
					}
				}
			}
			/* 如果bean里面没有用到AOP，就直接创建对象 */
			return className.getDeclaredConstructor().newInstance();
		} catch (Exception e) {
			throw new Exception("创建["+className.getName()+"]类型的bean对象出现错误",e);
		} 
	}

	/**
	 * @param name bean名称
	 * @param cls bean类型
	 * @param <T> 类型
	 * @return bean对象
	 * @throws Exception 异常
	 */
	public static <T> T getBean(String name,Class<T> cls) throws Exception {
		try {
			Map<String, FionaBeanModel> fionaBeanObjects = LoadHelper.getBeanObjectMap();
			return (T)fionaBeanObjects.get(name).getObj();
		} catch (Exception e) {
			throw new Exception("找不到name为["+name+"]的bean",e);
		}
	}
}
